--request.lua
-- 处理传过来的协议的调用
local filename = "tablerequest.lua"

require "skynet.manager"
require "mjexenum"

local skynet = require "skynet"
local filelog = require "filelog"
local tabletool = require "tabletool"
local timetool = require "timetool"
local timer = require "timer"
local cluster = require "skynet.cluster"

local json = require "cjson"
json.encode_sparse_array(true, 1, 1)

local CMD = {}
local service = nil
local tablelogic = nil

function CMD.init(caller)
	service = caller
	tablelogic = service:get_logicbyname("tablelogic")
end

--[Comment]
-- 处理发来的request类消息
--
function CMD.request( msgname, rid, roledata, request, ...)
    --转化request协议
    local is_request = false
    if msgname == "request" then
        msgname = request.msgname or ""
        request = json.decode(request.msgbody) or { }
        is_request = true
    end

    local f = CMD[msgname]
    if f == nil then
        return {retcode = EErrCode.ERR_INVALID_REQUEST, retstr = "消息不存在！"}
    end

    local tableobj = service.table_data
    if not tableobj.is_ingame then
        tableobj.last_heart_time = timetool.get_time()
    end
    
    local responsemsg = f(rid, roledata, request, ...)

    --request消息转化消息格式
    if is_request then
        return { msgname = msgname .. "R", msgbody = responsemsg}
    end
    
    return responsemsg
end

-------------------------

--[Comment]
-- 创建桌子
--正常情况table不会收到该消息
-- rid  玩家id
-- roledata 玩家信息 {info,money}
--
function CMD.createtable( rid, roledata,request)
    local table_service = service.table_data.table_service
    local table_index = service.table_data.index
    local diamond = roledata.money.diamond

    --重新通知gate，玩家进桌
    skynet.send(".router","lua","notice_gate_entertable",nil,rid,table_service,table_index,diamond)
    return { retcode = EErrCode.ERR_HAD_IN_TABLE,retstr = "已经在桌内!"}
end

--[Comment]
-- 进桌
-- 正常由router调起,request为空
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- ret 返回table_gameinfo（牌局信息）
--
function CMD.entertable( rid, roledata,request)
	local response = {}
    local playerinfo = roledata.info or { }
    local playermoney = roledata.money or { }
	local table_data = service.table_data

    --检测是否已在其他桌子内
    if cluster.call("gatenode", ".router", "check_role_state", rid, 0) then
        response.retcode = EErrCode.ERR_HAD_IN_TABLE
		response.retstr = "已经在桌子内"
		return	response
    end

     --删除桌子中，返回错误
    if table_data.isdeleting then
        response.retcode = EErrCode.ERR_INVALID_REQUEST
		response.retstr = "桌子已删除，不能进入！"
		return	response
    end

    --匹配场不能加入
    if table_data.is_matchtable and (not request or not request.is_auto) then
        response.retcode = EErrCode.ERR_INVALID_TABLE_INDEX
		response.retstr = "房间不存在"
		return	response
    end

    if request and request.table_index and request.table_index ~= table_data.index then
        response.retcode = 0--EErrCode.ERR_HAD_IN_TABLE
		response.retstr = ""--"已经在桌内！"
		return	response
    end

	if table_data.sitdown_player_num >= table_data.conf.max_player_num then
		response.retcode = EErrCode.ERR_TABLE_FULL
		response.retstr = "房间人数已满！"
		return	response
	end

    if table_data.sitdown_player_num > 0 
        and table_data.state > EMJTableState.TABLE_STATE_WAIT_ALL_READY then
        response.retcode = EErrCode.ERR_INVALID_REQUEST
		response.retstr = "游戏已开始，不能加入房间！"
		return	response
    end

    --自建房卡
	if table_data.table_type == EMJTableType.TABLE_TYPE_ZIJIAN_FANGKA then
		if table_data.conf.card_cost_type ~= nil and table_data.conf.card_cost_type ~= 1 then	-- AA制需要检查房卡是否足够,2 AA制，1房主
			local coin = playermoney.coin
			if not coin or coin < table_data.conf.card_cost / table_data.conf.max_player_num then
				response.retcode = EErrCode.ERR_NOT_ENOUGH_ROOMCARD
				response.retstr = "金币数量不够！"
				return	response
			end
		end
    elseif table_data.table_type == EMJTableType.TABLE_TYPE_ZIJIAN_ZUANSHI 
    or table_data.table_type == EMJTableType.TABLE_TYPE_JIN_BI_CHANG then
        --自建钻石,检查携带量
        table_data.conf.enter_diamond = table_data.conf.enter_diamond or 0
        local diamond = playermoney.diamond or 0
        if table_data.table_type == EMJTableType.TABLE_TYPE_JIN_BI_CHANG then
            diamond = diamond + (playermoney.coin or 0)
            if not playermoney.coin or playermoney.coin < table_data.service_fee then
                diamond = 0
            end
        end
        if diamond < table_data.conf.enter_diamond then
            response.retcode = EErrCode.ERR_NOT_ENOUGH_DIAMOND
			response.retstr = "余额不足！"
            if table_data.table_type == EMJTableType.TABLE_TYPE_JIN_BI_CHANG then
                response.retstr = "余额不足！"
            end
			return	response
        end
	end
	
    --检查旁观人数
	if table_data.conf.max_watch_playernum ~= nil 
		and table_data.cur_watch_playernum >= table_data.conf.max_watch_playernum then
		response.retcode = EErrCode.ERR_TABLE_FULL
		response.retstr = " 旁观人数过多!!!"
		return response
	end

    --获得座位
    seat = tablelogic.get_seat_by_rid(table_data, rid)
	if seat ~= nil then
		seat.playerinfo.rolename = playerinfo.rolename
		seat.playerinfo.logo = playerinfo.logo
		seat.playerinfo.sex = playerinfo.sex
        seat.playerinfo.ip_addr = playerinfo.ip_addr
        filelog.print("重进桌子!")
	end

    --执行进桌逻辑
    tablelogic.entertable(table_data, rid, roledata, request, seat)

    --返回牌局信息
	response.table_gameinfo = tablelogic.copy_table_gameinfo()

    --方法2：所有玩家都先加入allrids列表，玩家坐下时，再从allrids删除
    --table_data.allrids[rid] = 1  -- 增加一个玩家

	return response
end

--[Comment]
-- 坐下
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- request 请求包
-- ret 
--
function CMD.sitdowntable(rid, roledata, request)
	local responsemsg = { }

    local seat
	local table_data = service.table_data

    if table_data.conf.table_type == EMJTableType.TABLE_TYPE_ZIJIAN_ZUANSHI then
        local playermoney = roledata.money
        playermoney.diamond = playermoney.diamond or 0
        if playermoney.diamond < table_data.conf.enter_diamond then
                responsemsg.retcode = EErrCode.ERR_NOT_ENOUGH_DIAMOND
			    responsemsg.retstr = "余额不足,不能坐下！"
			    return	responsemsg
        end
    end

    if table_data.conf.table_type == EMJTableType.TABLE_TYPE_JIN_BI_CHANG then
        local playermoney = roledata.money
        playermoney.coin = playermoney.coin or 0 
        local coin = (playermoney.diamond or 0) + playermoney.coin
        if playermoney.coin < table_data.service_fee or coin < table_data.conf.enter_diamond then
            responsemsg.retcode = EErrCode.ERR_NOT_ENOUGH_DIAMOND
		    responsemsg.retstr = "余额不足,不能坐下！"
		    return	responsemsg
        end
    end

	seat = tablelogic.get_seat_by_rid(table_data, rid)
	local playerinfo = roledata.info
	if seat ~= nil then
		seat.playerinfo.rolename = playerinfo.rolename
		seat.playerinfo.logo = playerinfo.logo
		seat.playerinfo.sex = playerinfo.sex
        seat.playerinfo.ip_addr = playerinfo.ip_addr
        if seat.state ~= EMJSeatState.SEAT_STATE_NO_PLAYER 
        and not table_data.is_matchtable then
            responsemsg.retcode = EErrCode.ERR_HAD_IN_SEAT
            responsemsg.retstr = "已经在座位上!"
        end
		return responsemsg
	else
		if tablelogic.is_full(table_data) then
			responsemsg.retcode = EErrCode.ERR_TABLE_FULL
			responsemsg.retstr = "当前桌子已经满了！"
			return responsemsg
		end
		if request.seat_index == 0 then
			seat = tablelogic.get_emptyseat_by_index(table_data, nil)
		else
			seat = tablelogic.get_emptyseat_by_index(table_data, request.seat_index)
		end

		if seat == nil then
			responsemsg.retcode = EErrCode.ERR_NO_EMPTY_SEAT
			responsemsg.retstr = "当前桌子没有空座位了！"
			return responsemsg
		end
		if seat.state ~= EMJSeatState.SEAT_STATE_NO_PLAYER then
			responsemsg.retcode = EErrCode.ERR_NOT_NO_PLAYER
			responsemsg.retstr = "座位不是没有玩家的状态！"
			return responsemsg
		end
		--增加桌子人数计数 
		table_data.sitdown_player_num = table_data.sitdown_player_num + 1		
	end
	tablelogic.sitdowntable(table_data, rid, request, seat, roledata)
 
	responsemsg.seat_index = seat.index

	return responsemsg
end

--[Comment]
-- 准备
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- request 请求包
-- ret 
--
function CMD.gameready(rid, roledata, request)
	local responsemsg = {
	}

	local table_data = service.table_data
	local seat = tablelogic.get_seat_by_rid(table_data, rid)

    if table_data.conf.table_type == EMJTableType.TABLE_TYPE_ZIJIAN_ZUANSHI then
        local playermoney = roledata.money
        playermoney.diamond = playermoney.diamond or 0
        if playermoney.diamond < table_data.conf.leave_diamond then
            responsemsg.retcode = EErrCode.ERR_NOT_ENOUGH_DIAMOND
			responsemsg.retstr = "您的余额不足，请前往充值"
			return	responsemsg
        end
    end

    if table_data.conf.table_type == EMJTableType.TABLE_TYPE_JIN_BI_CHANG then
        local playermoney = roledata.money
        playermoney.coin = playermoney.coin or 0
        local coin = (playermoney.diamond or 0) + playermoney.coin
        if playermoney.coin < table_data.service_fee or coin < table_data.conf.leave_diamond then
            responsemsg.retcode = EErrCode.ERR_NOT_ENOUGH_DIAMOND
			responsemsg.retstr = "您的余额不足，请前往充值"
			return	responsemsg
        end
    end

	if seat == nil then
		responsemsg.retcode = EErrCode.ERR_HAD_STANDUP
		responsemsg.retstr = "玩家不在座位上！"
		return responsemsg
	end

	if seat.state == EMJSeatState.SEAT_STATE_WAIT_START then
        if not table_data.is_matchtable then
            responsemsg.retcode = EErrCode.ERR_INVALID_PARAMS
		    responsemsg.retstr = "已经准备！"
        end
		return responsemsg
	end

	if seat.state ~= EMJSeatState.SEAT_STATE_WAIT_READY then
		responsemsg.retcode = EErrCode.ERR_HAD_STANDUP
		responsemsg.retstr = "座位状态不是等待准备状态！"
		return responsemsg
	end

	seat.state = EMJSeatState.SEAT_STATE_WAIT_START

    ---取消准备倒计时
	if seat.ready_timer_id > 0  then 
		timer.cleartimer(seat.ready_timer_id)
		seat.ready_timer_id = -1
	end
	tablelogic.gameready(table_data, request, seat, roledata)
    responsemsg.rid = rid
    responsemsg.seat_index = seat.index
    responsemsg.is_ready = true
    responsemsg.is_tuoguan = false

	return responsemsg
end

--[Comment]
-- 执行玩家操作
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- request 请求包
-- ret 
--
function CMD.huansanzhang(rid, roledata, request)
    local responsemsg = {}

	local tableobj = service.table_data
	local seat = tablelogic.get_seat_by_rid(tableobj, rid)

	if seat == nil then
		responsemsg.retcode = EErrCode.ERR_HAD_STANDUP
		responsemsg.retstr = "玩家不在座位上！"
		return responsemsg
	end

    if tableobj.state ~= EMJTableState.TABLE_STATE_WAIT_MJ_HUAN_SAN_ZHANG then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "当前不能执行换三张操作！"
		return responsemsg
    end

    if seat.had_huansanzhang then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "已经操作过！"
		return responsemsg
    end

    if not request.exchange_cards or #(request.exchange_cards) ~= 3 then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "错误的换牌牌组！"
		return responsemsg
    end

    tablelogic.huansanzhang(tableobj, rid, request, seat)

    return responsemsg
end

--[Comment]
-- 执行玩家操作
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- request 请求包
-- ret 
--
function CMD.dingque(rid, roledata, request)
    local responsemsg = {}

	local tableobj = service.table_data
	local seat = tablelogic.get_seat_by_rid(tableobj, rid)

	if seat == nil then
		responsemsg.retcode = EErrCode.ERR_HAD_STANDUP
		responsemsg.retstr = "玩家不在座位上！"
		return responsemsg
	end

    if tableobj.state ~= EMJTableState.TABLE_STATE_WAIT_MJ_DINGQUE then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "当前不能执行定缺操作！"
		return responsemsg
    end

    if seat.que_cardcolor then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "已经操作过！"
		return responsemsg
    end

    if not request.que_color or request.que_color < 1 or  request.que_color > 3 then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "错误的缺牌花色！"
		return responsemsg
    end

    tablelogic.dingque(tableobj, rid, request, seat)

    return responsemsg
end

--[Comment]
-- 执行玩家操作
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- request 请求包
-- ret 
--
function CMD.doaction(rid, roledata, request)
	local responsemsg = {}

	local tableobj = service.table_data
	local seatlogic = service:get_logicbyname("seatlogic")
	local seat = tablelogic.get_seat_by_rid(tableobj, rid)

	if seat == nil then
		responsemsg.retcode = EErrCode.ERR_HAD_STANDUP
		responsemsg.retstr = "玩家不在座位上！"
		return responsemsg
	end
    
    if seat.is_tuoguan then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "托管中,请先取消托管！"
		return responsemsg
    end

    if tableobj.action_player_list == nil then
        responsemsg.retcode = 0
		responsemsg.retstr = ""--"当前不能操作！"
		return responsemsg
    end

    local action_player = tableobj.action_player_list[rid]
    if action_player == nil then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "未轮到您操作！"
		return responsemsg
    end

    if action_player.action_state == EMJActionState.DONE then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "您已经操作过！"
		return responsemsg
    elseif action_player.action_state == EMJActionState.DOING then
        responsemsg.retcode = EErrCode.ERR_DEADING_LASTREQ
        responsemsg.retstr = "您已经操作过了！"
		return responsemsg
    elseif tableobj.conf.table_type ~= EMJTableType.TABLE_TYPE_ZIJIAN_FANGKA and
     timetool.get_time() >= tableobj.action_timeout_time then
        responsemsg.retcode = EErrCode.ERR_SERVER_EXPIRED
        responsemsg.retstr = "操作已超时！"
		return responsemsg
    end

    --判断是否为合法操作
    local error_action = true
    for i,action_type in pairs(action_player.wait_action_types) do
        if request.action_type == action_type then
            error_action = false
            break
        end
    end
    if error_action then
         responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "错误的操作！"
		return responsemsg
    end
 
	if tableobj.state ~= EMJTableState.TABLE_STATE_WAIT_CLIENT_ACTION then
        responsemsg.retcode = 0
        responsemsg.retstr = ""--"当前不能操作！"
		return responsemsg
    end
    local is_ok,err_str = tablelogic.doaction(tableobj, rid, request, seat)
	if not is_ok then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = err_str
    else
        responsemsg.action_type = request.action_type
        responsemsg.is_ok = true
    end

	return responsemsg
end

--[Comment]
-- 主动离桌
-- rid  玩家id
-- roledata 玩家信息 {info,money}
-- request 请求包
-- ret 
--
function CMD.leavetable(rid, roledata, request)
	local responsemsg = {}
	local table_data = service.table_data
	local seat

    --[[
	if request.table_index and request.table_index ~= table_data.index then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "无效的桌号！"
		return responsemsg
	end
    ]]

    --房卡场，退出就是解散
    if table_data.table_type == EMJTableType.TABLE_TYPE_ZIJIAN_FANGKA then
        if rid == table_data.create_rid then
            return CMD.disbandtable(rid, roledata, request)
        end
    end

	seat = tablelogic.get_seat_by_rid(table_data, rid)
	if seat == nil then --在旁观列表，直接离开
		local diamond = nil
        if table_data.waits[rid] then
            diamond = table_data.waits[rid].playerinfo.diamond
        end
		tablelogic.leavetable(table_data, request, rid,diamond)	
		return responsemsg
	end

	----非练习场，如果玩家在游戏中,不能让他退出房间
    if table_data.table_type ~= EMJTableType.TABLE_TYPE_LIAN_XI_CHANG then
	    if not tablelogic.is_onegameend(table_data) then
		    responsemsg.retcode = EErrCode.ERR_PLAYER_IN_GAME
		    responsemsg.retstr = "房间正在游戏中,不能退出！"
		    return responsemsg
	    end
    end

    --先站起，再离开
    local diamond = seat.playerinfo.diamond
	tablelogic.standuptable(table_data, request, seat)
	tablelogic.leavetable(table_data, request, rid,diamond)	

    responsemsg.rid = rid
	responsemsg.table_index = table_data.index

	return responsemsg
end

--
--断线重连
--
-- 获得桌子状态，获得操作状态
-- 将桌子状态、操作状态、桌子信息、座位信息、玩家信息发给客户端
--
function CMD.reentertable(rid, roledata, request)
	local responsemsg = {}

    filelog.print("-------------reenter table--------",rid)
    local seatlogic = service:get_logicbyname("seatlogic")
	local tableobj = service.table_data
	local seat
	local playerinfo = roledata.info
    local playermoney = roledata.money
    local table_state = tableobj.state

     --桌子索引错误
    if request and request.table_index and request.table_index ~= tableobj.index then
        --从当前桌子离开
        skynet.send(".router","lua","leave_table",nil,rid,tableobj.index,roledata.money.diamond)
        return {retcode = EErrCode.ERR_INVALID_REQUEST,retstr = "错误的桌子索引号！"}
    end

	seat = tablelogic.get_seat_by_rid(tableobj, rid)
	if seat ~= nil then
		seat.playerinfo.rolename = playerinfo.rolename
		seat.playerinfo.logo = playerinfo.logo
		seat.playerinfo.sex = playerinfo.sex

        --初始化seat数据
	    seat.playerinfo.ip_addr = roledata.ip_addr or playerinfo.ip_addr
        seat.playerinfo.gps_addr = roledata.gps_addr or playerinfo.gps_addr
        seat.playerinfo.intro = playerinfo.intro or ""
	    seat.playerinfo.fangka = playermoney.fangka or 0
	    seat.playerinfo.diamond = playermoney.diamond or 0
        seat.playerinfo.lock_diamond = playermoney.lock_diamond or 0
	end

	if seat == nil then
		local ret = CMD.entertable(rid,roledata)
        if ret and ret.retcode ~= nil then
             skynet.send(".router","lua","leave_table",nil,rid,tableobj.index,roledata.money.diamond)
        end
        return ret
	end

    --返回游戏信息大集合
	responsemsg.table_gameinfo = tablelogic.copy_table_gameinfo()
    local seatinfo = responsemsg.table_gameinfo.seat_gameinfos[seat.index]
    seatinfo.cards = tabletool.deepcopy(seat.cards) --添加自己的手牌

    local other_seatinfos = responsemsg.table_gameinfo.seat_gameinfos
    for k,tmpseat in pairs(other_seatinfos) do
        if tmpseat.rid ~= seat.rid and tmpseat.di_cards then
            for i,di_card in pairs(tmpseat.di_cards) do
                if di_card.gang_peng_type == EMJGangPengType.GANGPENG_TYPE_ANGANG then
                    tmpseat.di_cards[i].card = -1   --暗杠不显示牌值
                end
            end
        end
    end
   
    local timerid = timer.settimer(3,"reenter_table",{seat_index = seat.index })

    --更改断线状态
    if seat.is_disconnected then
	    seat.is_disconnected = false

        --保存断线重连记录
        if seat.cards and #(seat.cards) > 0 then
            local cur_time = timetool.get_time()
            local item = tostring(cur_time) .. "_" .. seat.rid .."_" .. "reentertable"
            tablelogic.save_playback_record(item)
        end
    end

	return responsemsg
end

--
--申请解散桌子
--
function CMD.disbandtable(rid, roledata, request)
	local tableobj = service.table_data

	local responsemsg = { }

    if request.table_index and request.table_index ~= tableobj.index then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "无效的桌号！"
		return responsemsg
	end

	if tableobj.conf.table_type ~= EMJTableType.TABLE_TYPE_ZIJIAN_FANGKA then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "不是房卡场,不能解散!"
		return responsemsg
	end
	
	local launch_player_seat = tablelogic.get_seat_by_rid(tableobj, rid)
	if launch_player_seat == nil then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "玩家不在座位上,不能解散！"
		return responsemsg
	end

    if tableobj.playerdisbandlist ~= nil then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "正在处理上一次解散请求！"
		return responsemsg
    end

	---一局开始前，房主可以直接解散，其他人不能解散
	if tableobj.curr_to_num >= 1 then
		------广播所有玩家
        tableobj.disband_timeout_time = timetool.get_time() + 180
        tableobj.disband_player_index = launch_player_seat.index

        --保存申请解散者
        local seatlogic = service:get_logicbyname("seatlogic")
        tableobj.playerdisbandlist =  { }
        for index,tmpseat in pairs(tableobj.seats) do
            if not seatlogic.is_empty(tmpseat) then
                local item = {
                    rid = tmpseat.rid,
                    rolename = tmpseat.playerinfo.rolename,
                    is_agree = nil,
                }
               
                if tmpseat.rid == rid then
                    item.is_agree = 1
                end
                table.insert(tableobj.playerdisbandlist,item)
            end
        end

		----发起者默认是同意解散,不发送操作通知给他
		local noticemsg = {
			rid = launch_player_seat.rid,
			seat_index = launch_player_seat.index,
			action_timeout_time = tableobj.disband_timeout_time,
			apply_player_name = launch_player_seat.playerinfo.rolename,
            player_disband_list = tabletool.deepcopy(tableobj.playerdisbandlist),
		}

		tableobj.disband_table_timer_id = timer.settimer(180 * 100, "applydisband")
		tablelogic.sendmsg_to_otheralltableplayer(tableobj,rid, "disbandtableN", noticemsg)
	else
		if rid ~= tableobj.create_rid then
            responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		    responsemsg.retstr = "游戏开始前,只有房主才能解散！"
		    return responsemsg
        end

        --游戏开始前，直接解散
        tablelogic.disbandtable(tableobj)

        tableobj.playerdisbandlist = nil
		--tablelogic.sendmsg_to_alltableplayer(tableobj, "disbandresultN", {table_index = tableobj.index,is_success = true})
	end

	return responsemsg
end

--
--响应解散桌子请求
--
function CMD.disbanddeal(rid, roledata, request)
	local table_data = service.table_data
	local responsemsg = {}

	local seat = tablelogic.get_seat_by_rid(table_data, rid)
	if seat == nil then
		responsemsg.retcode = EErrCode.ERR_NOT_INTABLE
		responsemsg.retstr = "玩家不在座位上！"
		return responsemsg
	end

    if table_data.playerdisbandlist == nil then
        responsemsg.retcode = EErrCode.ERR_SERVER_EXPIRED
		responsemsg.retstr = "解散请求已过期！"
		return responsemsg
    end

    if request.is_agree ~= 1 and request.is_agree ~= 2 then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "无效的请求！"
		return responsemsg
    end

    local i = 0
    for j,v in pairs(table_data.playerdisbandlist) do
        if v.rid == rid then
            i = j
            break
        end
    end
    
	----先判断玩家是否已经操作过
	if table_data.playerdisbandlist[i].is_agree ~= nil then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "你已经操作过"
		return responsemsg
	end

	----记录玩家在这轮的操作
	table_data.playerdisbandlist[i].is_agree = request.is_agree or 2

	----向其他玩家通知该玩家的操作结果
	local noticemsg = {
		rid = seat.rid,
        rolename = seat.playerinfo.rolename,
		player_disband_list = tabletool.deepcopy(table_data.playerdisbandlist),
	}
	tablelogic.sendmsg_to_alltableplayer(table_data, "disbanddealN", noticemsg)

	----判断本轮操作是否完成,完成则发送最终结果
	local isallover,agree_num,refuse_num = tablelogic.is_allplayer_response_disband(table_data)
    if request.is_agree == 2 then
        isallover = true
        refuse_num = 1
    end

	if isallover == true then
        local is_success = false
        if refuse_num == 0 then
            is_success = true
        end

        local noticemsg = {
            table_index = table_data.index,
            is_success = is_success,
        }

		---清除玩家操作记录,通知解散结果
		table_data.playerdisbandlist = nil
        table_data.disband_player_index = nil
        table_data.disband_timeout_time = 0
		tablelogic.sendmsg_to_alltableplayer(table_data, "disbandresultN", noticemsg)

        --解散成功
		if is_success then
			tablelogic.disbandtable(table_data)
		end

        if table_data.disband_table_timer_id > 0 then
            timer.cleartimer(table_data.disband_table_timer_id)
            table_data.disband_table_timer_id = -1
        end
	end

	return responsemsg
end


--
--玩家断开连接
--
function CMD.disconnect(rid, roledata,request)
	filelog.print("----tablerequest.disconnect----", rid)
	local tableobj = service.table_data
    local seat = tablelogic.get_seat_by_rid(tableobj,rid)
    if seat then
        tablelogic.disconnect(tableobj,request,seat)
    end

    return true
end

--
--站起
--
function CMD.standuptable(rid, roledata,request)
    local responsemsg = { }
    local tableobj = service.table_data
    local seat = tablelogic.get_seat_by_rid(tableobj,rid)

    --[[
    if request.table_index and request.table_index ~= tableobj.index then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "无效的桌号！"
		return responsemsg
	end
    ]]

    if seat == nil then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "玩家不在座位上!"
        return responsemsg
    end

    --如果玩家在游戏中,不能让他退出房间
    if tableobj.table_type ~= EMJTableType.TABLE_TYPE_LIAN_XI_CHANG then
	    if not tablelogic.is_onegameend(tableobj) then
		    responsemsg.retcode = EErrCode.ERR_PLAYER_IN_GAME
		    responsemsg.retstr = "房间正在游戏中,不能退出！"
		    return responsemsg
	    end
    end

    tablelogic.standuptable(tableobj, request, seat)

    return responsemsg
end

--
--托管
--
function CMD.dotuoguan(rid, roledata,request)
    local responsemsg = { }
    local tableobj = service.table_data
    local seat = tablelogic.get_seat_by_rid(tableobj,rid)

    if not tableobj.is_ingame then
		responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "游戏中才能托管！"
		return responsemsg
	end

    if tableobj.table_type == EMJTableType.TABLE_TYPE_ZIJIAN_FANGKA then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "房卡场不能托管！"
		return responsemsg
    end

    if seat == nil then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "玩家不在座位上！"
		return responsemsg
    end

    if seat.is_tuoguan == request.is_tuoguan then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
		responsemsg.retstr = "不能重复进行托管操作！"
		return responsemsg
    end

    tablelogic.dotuoguan(tableobj,request,seat)

    return responsemsg
end

--
--取消匹配
--
function CMD.cancelmatch(rid, roledata,request)
    filelog.sys_error("已经匹配成功，不能取消匹配",rid,service.table_data.code)
    return {retcode = EErrCode.ERR_HAD_IN_TABLE, retstr = "已经匹配成功，不能取消匹配"}
end

--
--清除玩家状态
--
function CMD.clear_player_state(rid, roledata, request)
    if not rid or rid <= 0 then
        return
    end

    local tableobj = service.table_data
    if tableobj.state == EMJTableState.TABLE_STATE_WAIT_ALL_READY
    or tableobj.state == EMJTableState.TABLE_STATE_WAIT_PLAYER_SITDOWN then
        CMD.leavetable(rid, roledata, request)
    end
end

--
--离开游戏（游戏中离桌）
--
function CMD.leavegame(rid, roledata, request)
    local responsemsg = { }
    local tableobj = service.table_data
    local seat = tablelogic.get_seat_by_rid(tableobj,rid)

    if seat == nil then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "玩家不在座位上!"
        return responsemsg
    end

    --金币和钻石场才能退出
    if tableobj.table_type ~= EMJTableType.TABLE_TYPE_ZIJIAN_ZUANSHI
    and tableobj.table_type ~= EMJTableType.TABLE_TYPE_JIN_BI_CHANG then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "当前不能退出!"
        return responsemsg
    end

    --胡牌才能离桌
    if tableobj.is_ingame and seat.is_hupai and seat.is_can_half_leave then
        tablelogic.leavegame(tableobj,request,seat)
    else
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "错误的操作!"
        return responsemsg
    end

    return responsemsg
end

------------------------------------------------------------------

return CMD